import * as validate from '@/utils/validate';
import * as storage from '@/utils/storage';
import * as tools from '@/utils/util';
import * as api from '@/api/api'
//import * as superagent from 'superagent';

//TokenKey
export const TokenKey = 'Access-Token';

//古诗词合集地址
const poetAddr = JSON.parse(window.poetAddrArray || `[]`);
//提示语录合集
const arr = JSON.parse(window.maxim || `[]`);

/**
 * @function 获取打招呼信息
 */
export function timeFix() {
    const time = new Date();
    const hour = time.getHours();
    return hour < 9 ?
        '早上好' :
        hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好';
}

/**
 * @function 获取随机诗词内容
 */
export async function queryPoet() {

    //索引指针
    let index = Math.floor(Math.random() * poetAddr.length);
    index = index < poetAddr.length ? index : poetAddr.length - 1;

    //获取诗文网站
    const poetaddr = poetAddr[index];

    //将数据存入缓存
    var poetarray = storage.getStore(poetaddr);

    //获取原先已经缓存的诗词内容
    var temp = storage.getStore(`system_poet_array`);

    //如果没有获取到诗词内容
    if (tools.isNull(temp)) {
        temp = [];
    } else if (temp.length >= 1000 && tools.isNull(poetarray)) {
        poetarray = temp.slice(0, 1000);
    }

    //如果没有获取到诗文
    if (typeof poetarray == 'undefined' || poetarray == null || poetarray == '') {
        //获取诗文内容
        poetarray = await superagent.get(poetaddr).set('accept', 'json');
        //只获取数组内容
        poetarray = poetarray.body;
        //将数据存入缓存
        //storage.setStore(poetaddr, JSON.stringify(poetarray), 3600 * 24 * 365 * 10);
        //将诗词数组放入常用诗词中
        storage.setStore(`system_poet_array`, JSON.stringify(temp.concat(poetarray).slice(0, 1000)), 3600 * 24 * 7);
    }

    //随机获取一首诗词
    index = Math.floor(Math.random() * poetarray.length);
    index = index < poetarray.length ? index : poetarray.length - 1;

    //获取到诗词内容
    const poet = poetarray[index];
    //打印诗词内容
    console.log("诗词内容：" + JSON.stringify(poet));

    //定义诗词标题
    const title = tools.isNull(poet.title) ? '' : `《${poet.title}》`;

    //诗词作者
    const author = tools.isNull(poet.author) ? '' : ` — ${poet.author}`;

    //定义返回结果
    const result = `『 ${poet.paragraphs} 』${author} ${title}`;

    //保存诗文内容
    storage.setStore("system_poet_content", result, 10);

    //返回诗词内容
    return result;
}

/**
 * @function 获取
 */
export function welcome() {

    //查询诗词
    queryPoet().then((poet) => {
        //打印诗词
        console.log(poet);
    });

    //获取诗词数组
    var poetarry = storage.getStore(`system_poet_array`);

    //诗词随机指针
    var index = Math.floor(Math.random() * arr.length);
    index = index < arr.length ? index : arr.length - 1;

    //获取缓存的诗文内容
    var content = storage.getStore("system_poet_content");

    //如果诗词数组不为空，且诗词内容为空，则获取随机诗词
    if (!tools.isNull(poetarry) && tools.isNull(content)) {

        //诗词随机指针
        var pindex = Math.floor(Math.random() * poetarry.length);
        pindex = pindex < poetarry.length ? pindex : poetarry.length - 1;

        //获取随机诗词
        content = poetarry[pindex];

        //定义诗词标题
        let title = tools.isNull(content.title) ? '' : `《${content.title}》`;

        //诗词作者
        let author = tools.isNull(content.author) ? '' : ` — ${content.author}`;

        //定义返回结果
        content = `『 ${content.paragraphs} 』${author} ${title}`;

    }

    //如果存在诗文内容，则使用诗文内容，否则，诗文默认配置
    if (tools.isNull(content) || (new Date().getTime() % 2 == 0)) {
        return arr[index];
    } else {
        return content;
    }

}

/**
 * 触发 window.resize
 */
export function triggerWindowResizeEvent() {
    let event = document.createEvent('HTMLEvents');
    event.initEvent('resize', true, true);
    event.eventType = 'message';
    window.dispatchEvent(event);
}

/**
 * 过滤对象中为空的属性
 * @param obj
 * @returns {*}
 */
export function filterObj(obj) {
    if (!(typeof obj == 'object')) {
        return;
    }

    for (var key in obj) {
        if (
            obj.hasOwnProperty(key) &&
            (obj[key] == null || obj[key] == undefined || obj[key] === '')
        ) {
            delete obj[key];
        }
    }
    return obj;
}

/**
 * 时间格式化
 * @param value
 * @param fmt
 * @returns {*}
 */
export function formatDate(value, fmt) {
    //如果时间格式含有T，yyyy-MM-ddThh:mm:ss,yyyy-MM-ddThh:mm:ss.SSSZ，这样做可以自动把+0:00时区的时间转为+8:00的时间
    if (typeof value == 'string' && value.includes('T')) {
        value = new Date(value);
    }

    //正则表达式
    var regPos = /^\d+(\.\d+)?$/;

    if (regPos.test(value) || value instanceof Date) {
        //如果是数字
        let getDate = value instanceof Date ? value : new Date(value);
        let o = {
            'M+': getDate.getMonth() + 1,
            'd+': getDate.getDate(),
            'h+': getDate.getHours(),
            'm+': getDate.getMinutes(),
            's+': getDate.getSeconds(),
            'q+': Math.floor((getDate.getMonth() + 3) / 3),
            S: getDate.getMilliseconds(),
        };
        if (/(y+)/.test(fmt)) {
            fmt = fmt.replace(
                RegExp.$1,
                (getDate.getFullYear() + '').substr(4 - RegExp.$1.length)
            );
        }
        for (let k in o) {
            if (new RegExp('(' + k + ')').test(fmt)) {
                fmt = fmt.replace(
                    RegExp.$1,
                    RegExp.$1.length === 1 ?
                    o[k] :
                    ('00' + o[k]).substr(('' + o[k]).length)
                );
            }
        }

        try {
            fmt = fmt.replace('T', ' ');
        } catch (error) {
            console.log('formate date error : ' + error);
        }

        return fmt;
    } else {
        //TODO
        try {
            if (typeof value == 'undefined' || value == null) {
                value = '--';
            }
            value = value.trim();
            fmt = value.substr(0, fmt.length);
            fmt = fmt.replace('T', ' ');
        } catch (error) {
            console.log('formate date error : ' + error);
        }

        return fmt;
    }
}

/**
 * @function 过滤空对象
 * @param {*} data
 */
export function deNull(data, defaultValue = '') {
    try {
        if (typeof data == 'undefined' || data == null || data == '' || JSON.stringify(data) == "{}") {
            return defaultValue;
        } else {
            return data;
        }
    } catch (error) {
        console.log(error);
    }
}

/**
 * @function 过滤空对象
 * @param {*} data
 */
export function isNull(data) {
    try {
        if (typeof data == 'undefined' || data == null || data == '' || JSON.stringify(data) == "{}") {
            return true;
        } else {
            return false;
        }
    } catch (error) {
        console.log(error);
    }
}

export function isBlank(data) {
    try {
        return isNull(data);
    } catch (error) {
        console.log(error);
    }
}

// 生成首页路由
export function generateIndexRouter(data) {
    let indexRouter = [{
            path: '/',
            name: 'dashboard',
            component: resolve =>
                require(['@/components/layouts/TabLayout'], resolve),
            meta: {
                title: '首页',
            },
            redirect: '/dashboard/analysis',
            children: [...generateChildRouters(data)],
        },
        {
            path: '/',
            name: 'dashboard',
            component: resolve =>
                require(['@/components/layouts/TabLayout'], resolve),
            meta: {
                title: '工作台',
            },
            redirect: '/dashboard/workplace',
            children: [...generateChildRouters(data)],
        },
    ];
    return indexRouter;
}

// 生成嵌套路由（子路由）

function generateChildRouters(data) {
    const routers = [];
    for (var item of data) {
        let component = '';
        if (item.component.indexOf('layouts') >= 0) {
            component = 'components/' + item.component;
        } else {
            component = 'views/' + item.component;
        }

        // eslint-disable-next-line
        let URL = (item.meta.url || '')
            .replace(/{{([^}}]+)?}}/g, (s1, s2) => eval(s2)); // URL支持{{ window.xxx }}占位符变量
        if (validate.isURL(URL)) {
            item.meta.url = URL;
        }

        let menu = {
            path: item.path,
            name: item.name,
            redirect: item.redirect,
            component: resolve => require(['@/' + component + '.vue'], resolve),
            hidden: item.hidden,
            meta: {
                title: item.meta.title,
                icon: item.meta.icon,
                url: item.meta.url,
                permissionList: item.meta.permissionList,
                keepAlive: item.meta.keepAlive,
            },
        };
        if (item.alwaysShow) {
            menu.alwaysShow = true;
            menu.redirect = menu.path;
        }
        if (item.children && item.children.length > 0) {
            menu.children = [...generateChildRouters(item.children)];
        }
        //判断是否生成路由
        if (item.route && item.route === '0') {
            //console.log(' 不生成路由 item.route：  '+item.route);
            //console.log(' 不生成路由 item.path：  '+item.path);
        } else {
            routers.push(menu);
        }
    }
    return routers;
}

/**
 * 深度克隆对象、数组
 * @param obj 被克隆的对象
 * @return 克隆后的对象
 */
export function cloneObject(obj) {
    return JSON.parse(JSON.stringify(obj));
}

/**
 * @function clone对象
 * @param {*} obj 被克隆对象
 */
export function clone(obj) {
    return JSON.parse(JSON.stringify(obj));
}

/**
 * 随机生成数字
 *
 * 示例：生成长度为 12 的随机数：randomNumber(12)
 * 示例：生成 3~23 之间的随机数：randomNumber(3, 23)
 *
 * @param1 最小值 | 长度
 * @param2 最大值
 * @return int 生成后的数字
 */
export function randomNumber() {
    // 生成 最小值 到 最大值 区间的随机数
    const random = (min, max) => {
        return Math.floor(Math.random() * (max - min + 1) + min);
    };
    if (arguments.length === 1) {
        let [length] = arguments;
        // 生成指定长度的随机数字，首位一定不是 0
        let nums = [...Array(length).keys()].map(
            i => (i > 0 ? random(0, 9) : random(1, 9))
        );
        return parseInt(nums.join(''));
    } else if (arguments.length >= 2) {
        let [min, max] = arguments;
        return random(min, max);
    } else {
        return Number.NaN;
    }
}

/**
 * 随机生成字符串
 * @param length 字符串的长度
 * @param chats 可选字符串区间（只会生成传入的字符串中的字符）
 * @return string 生成的字符串
 */
export function randomString(length, chats) {
    if (!length) length = 1;
    if (!chats) chats = '0123456789qwertyuioplkjhgfdsazxcvbnm';
    let str = '';
    for (let i = 0; i < length; i++) {
        let num = randomNumber(0, chats.length - 1);
        str += chats[num];
    }
    return str;
}

/**
 * 随机生成uuid
 * @return string 生成的uuid
 */
export function randomUUID() {
    let chats = '0123456789abcdef';
    return randomString(32, chats);
}

/**
 * 下划线转驼峰
 * @param string
 * @returns {*}
 */
export function underLine2CamelCase(string) {
    return string.replace(/_([a-z])/g, function(all, letter) {
        return letter.toUpperCase();
    });
}

/**
 * 判断是否显示办理按钮
 * @param bpmStatus
 * @returns {*}
 */
export function showDealBtn(bpmStatus) {
    if (bpmStatus != '1' && bpmStatus != '3' && bpmStatus != '4') {
        return true;
    }
    return false;
}

/**
 * 增强CSS，可以在页面上输出全局css
 * @param css 要增强的css
 * @param id style标签的id，可以用来清除旧样式
 */
export function cssExpand(css, id) {
    let style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = `@charset "UTF-8"; ${css}`;
    // 清除旧样式
    if (id) {
        let $style = document.getElementById(id);
        if ($style != null) $style.outerHTML = '';
        style.id = id;
    }
    // 应用新样式
    document.head.appendChild(style);
}

/**
 * 检查字符串是否包含中文
 * @param {*} val
 */
export function existChinese(val) {
    var reg = new RegExp('[\\u4E00-\\u9FFF]+', 'g');
    return reg.test(val);
}

/**
 * 获取URL参数值
 * @param {*} val
 */
export function queryUrlString(name) {
    try {

        var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
        var r = window.location.search.substr(1).match(reg); //search,查询？后面的参数，并匹配正则
        if (r != null) return unescape(r[2]);
    } catch (error) {
        console.error(error);
    }
    return '';
}

/**
 * 获取URL参数值
 * @param {*} val
 */
export function queryUrl(name) {
    try {

        var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
        var r = window.location.search.substr(1).match(reg); //search,查询？后面的参数，并匹配正则
        if (r != null) return unescape(r[2]);

    } catch (error) {
        console.error(error);
    }
    return '';
}

/**
 * @function 检测字符串是否包含字符函数
 * @param {*} origin 
 * @param {*} arg 
 */
export function contain(origin, arg) {

    //设置前后缀信息
    origin = `,${origin},`;

    //设置包含的用户
    var ready = '';

    //设置数组信息
    var array = null;

    try {
        array = arg.split(',');

        //遍历数据，并查询出含有的用户数据
        for (var item of array) {
            ready = origin.includes(`,${item},`) ? `${ready},${item}` : ready;
        }

    } catch (error) {
        console.log(error);
    }

    //去掉字符串开头的逗号
    if (ready.startsWith(',')) {
        ready = ready.substring(1);
    }

    //去掉字符串结尾的逗号
    if (ready.endsWith(',')) {
        ready = ready.substring(0, ready.length - 1);
    }

    //返回包含的用户数据
    return ready;
}

/**
 * 计算两个日期之间的天数
 */
export function queryDateDiff(date1, date2) {
    //如果被解析日期格式为字符串，则先将字符串解析为日期格式
    if (Object.prototype.toString.call(date1).includes('String')) {
        try {
            date1 = parseDate(formatDate(date1, 'yyyy-MM-dd hh:mm:ss'));
            date2 = parseDate(formatDate(date2, 'yyyy-MM-dd hh:mm:ss'));
        } catch (e) {
            date1 = parseDate(date1);
            date2 = parseDate(date2);
        }
    }

    var beginDate = date1;
    var endDate = date2;

    //日期差值,即包含周六日、以天为单位的工时，86400000=1000*60*60*24.
    var workDayVal = (endDate - beginDate) / 86400000;
    //工时的余数
    var remainder = workDayVal % 7;
    //工时向下取整的除数
    var divisor = Math.floor(workDayVal / 7);
    var weekendDay = 2 * divisor;

    //起始日期的星期，星期取值有（1,2,3,4,5,6,0）
    var nextDay = beginDate.getDay();
    //从起始日期的星期开始 遍历remainder天
    for (var tempDay = remainder; tempDay >= 1; tempDay--) {
        //第一天不用加1
        if (tempDay == remainder) {
            nextDay = nextDay + 0;
        } else if (tempDay != remainder) {
            nextDay = nextDay + 1;
        }
        //周日，变更为0
        if (nextDay == 7) {
            nextDay = 0;
        }

        //周六日
        if (nextDay == 0 || nextDay == 6) {
            weekendDay = weekendDay + 1;
        }
    }
    //获取含有小数位的天数
    var timeFloat = parseFloat(workDayVal);
    //获取整数位的天数
    var timeInt = parseInt(workDayVal);
    //实际工时（天） = 起止日期差 - 周六日数目。
    workDayVal = parseInt(workDayVal - weekendDay);

    //取相差天数的小数位
    var decpart = timeFloat - timeInt;

    //如果小数位的天数大于0.5（3小时），按一天统计，如果大于0，按半天统计
    if (decpart * 24 > 4) {
        decpart = 1;
    } else if (decpart > 0) {
        decpart = 0.5;
    } else {
        decpart = 0;
    }

    return workDayVal + decpart;
}

/**
 * @function 字符串转为日期
 * @param {*} date
 */
export function parseDate(date) {
    var t = Date.parse(date);
    try {
        if (!isNaN(t)) {
            return new Date(Date.parse(date.replace(/-/g, '/')));
        }
    } catch (error) {
        console.log(error);
    }
    return new Date();
}

/**
 * @function 解析JSON对象
 * @param {*} json
 */
export function parseJSON(json) {
    try {
        return JSON.parse(json);
    } catch (e) {
        console.log('err', e);
    }
    return [];
}

/**
 * 清理空值，对象
 * @param children
 * @returns {*[]}
 */
export function filterEmpty(children = []) {
    return children.filter(c => c.tag || (c.text && c.text.trim() !== ''))
}

/**
 * @function 去除字符串中html标签
 * @param {*} str 
 */
export function delHtmlTag(str) {
    try {
        if (isNull(str)) {
            return ""; //去掉所有的html标记
        } else {
            return deNull(str).replace(/<[^>]+>/g, "").replace(/&nbsp;/g, ""); //去掉所有的html标记
        }
    } catch (error) {
        console.log(error);
    }
}

/**
 * @function 字符串缩略函数
 * @param {*} str 
 */
export function abbreviation(str, length = 75) {
    try {

        if (deNull(str).length < length) {
            return deNull(str).trim();
        } else {
            return deNull(str).trim().substring(0, length) + '...';
        }
    } catch (error) {
        console.log(error);
    }
}

/**
 * @function 合成唯一编码
 */
export function queryUniqueID(length = 32) {
    //日期格式化
    var timestamp = new Date().getTime();
    //定义动态编码
    var id = formatDate(timestamp, "yyyyMMddhhmmssS");
    //打印日志
    console.log('动态编号 :' + id);
    //定义随机编码
    var random = (Math.floor(Math.random() * 100000000000000000000) + "") + (Math.floor(Math.random() * 100000000000000000000) + "");
    //打印随机编码
    console.log('随机编号 :' + random);
    //合成动态编码
    id = (id + random).replace(/\./g, '').substring(0, length);
    //返回唯一编码
    return id;
}

/**
 * @function 设置缓存信息
 */
export function setStore(name, content, maxAge = null) {
    return storage.setStore(name, content, maxAge);
}

/**
 * @function 获取缓存信息
 */
export function getStore(name) {
    return storage.getStore(name);
}

/**
 * @function 清空缓存信息
 * @param {*} name 
 */
export function clearStore(name) {
    return storage.clearStore(name);
}

/**
 * @function 清空缓存信息
 */
export const clearAll = () => {
    return storage.clearAll();
}


/**
 * 重复值验证工具方法
 *
 * 使用示例：
 * { validator: (rule, value, callback) => validateDuplicateValue('sys_fill_rule', 'rule_code', value, this.model.id, callback) }
 *
 * @param tableName 被验证的表名
 * @param fieldName 被验证的字段名
 * @param fieldVal 被验证的值
 * @param dataId 数据ID，可空
 * @param callback
 */
export function validateDuplicateValue(tableName, fieldName, fieldVal, dataId, callback) {
    if (fieldVal) {
        let params = {
            tableName,
            fieldName,
            fieldVal,
            dataId
        }
        api.duplicateCheck(params).then(res => {
            res['success'] ? callback() : callback(res['message'])
        }).catch(err => {
            callback(err.message || err)
        })
    } else {
        callback()
    }
}

/**
 * 根据编码校验规则code，校验传入的值是否合法
 *
 * 使用示例：
 * { validator: (rule, value, callback) => validateCheckRule('common', value, callback) }
 *
 * @param ruleCode 编码校验规则 code
 * @param value 被验证的值
 * @param callback
 */
export function validateCheckRule(ruleCode, value, callback) {
    if (ruleCode && value) {
        value = encodeURIComponent(value)
        api.checkRuleByCode({
            ruleCode,
            value
        }).then(res => {
            res['success'] ? callback() : callback(res['message'])
        }).catch(err => {
            callback(err.message || err)
        })
    } else {
        callback()
    }
}

/**
 * 如果值不存在就 push 进数组，反之不处理
 * @param array 要操作的数据
 * @param value 要添加的值
 * @param key 可空，如果比较的是对象，可能存在地址不一样但值实际上是一样的情况，可以传此字段判断对象中唯一的字段，例如 id。不传则直接比较实际值
 * @returns {boolean} 成功 push 返回 true，不处理返回 false
 */
export function pushIfNotExist(array, value, key) {
    for (let item of array) {
        if (key && (item[key] === value[key])) {
            return false
        } else if (item === value) {
            return false
        }
    }
    array.push(value)
    return true
}

/**
 * 可用于判断是否成功
 * @type {symbol}
 */
export const succeedSymbol = Symbol()
    /**
     * 可用于判断是否失败
     * @type {symbol}
     */
export const failedSymbol = Symbol()

/**
 * 使 promise 无论如何都会 resolve，除非传入的参数不是一个Promise对象或返回Promise对象的方法
 * 一般用在 Promise.all 中
 *
 * @param promise 可传Promise对象或返回Promise对象的方法
 * @returns {Promise<any>}
 */
export function alwaysResolve(promise) {
    return new Promise((resolve, reject) => {
        let p = promise
        if (typeof promise === 'function') {
            p = promise()
        }
        if (p instanceof Promise) {
            p.then(data => {
                resolve({
                    type: succeedSymbol,
                    data
                })
            }).catch(error => {
                resolve({
                    type: failedSymbol,
                    error
                })
            })
        } else {
            reject('alwaysResolve: 传入的参数不是一个Promise对象或返回Promise对象的方法')
        }
    })
}

/**
 * @function JS Sleep休眠函数
 * @param {*} time 
 */
export const sleep = async(time = 1000) => {
    return new Promise((resolve) => setTimeout(resolve, time));
}